﻿using FastDFS.Client;
using System.IO;
using System.Net;
using up6.utils;

namespace up6.db.store
{
    /// <summary>
    /// FastDFS工具类
    /// </summary>
    public class FastDFSTool
    {
        private string groupName = "";
        private List<IPEndPoint> trackers = new List<IPEndPoint>();

        public static FastDFSTool build()
        {
            return new FastDFSTool();
        }

        public FastDFSTool()
        {
            var cr = new ConfigReader();
            var root = cr.m_files.SelectToken("$.FastDFS");
            var ip = root["ip"].ToString().Trim();
            var port = int.Parse(root["port"].ToString().Trim());
            this.groupName = root["group"].ToString().Trim();
            this.trackers.Add(new IPEndPoint(IPAddress.Parse(ip), port));
        }

        public static async Task<string> uploadAsync(byte[] contentByte, string fileExt)
        {
            FastDFSTool fdt = new FastDFSTool();
            var node = await fdt.nodeAsync();
            return await FastDFSClient.UploadAppenderFileAsync(node, contentByte, fileExt);
        }

        public static async Task<string> uploadAsync(Stream stm, string fileName)
        {
            FastDFSTool fdt = new FastDFSTool();
            var node = await fdt.nodeAsync();
            byte[] data = new byte[stm.Length];
            stm.Read(data, 0, data.Length);
            return await FastDFSClient.UploadFileAsync(node, data, fileName);
        }

        public static async Task remove(string fileName)
        {
            FastDFSTool fdt = new FastDFSTool();
            await FastDFSClient.RemoveFileAsync(fdt.nodeAsync().Result.GroupName, fileName);
        }

        public static async Task appendAsync(string fileName,byte[] data)
        {
            var fdt = new FastDFSTool();
            var node = await fdt.nodeAsync();
            await FastDFSClient.AppendFileAsync(node.GroupName, fileName, data);
        }

        public static async Task<byte[]> down(string fileName)
        {
            FastDFSTool fdt = new FastDFSTool();
            var node = await fdt.nodeAsync();
            return await FastDFSClient.DownloadFileAsync(node, fileName);
        }

        public static async Task<byte[]> downAsync(string fileName,long offset,long size)
        {
            Stream stm = new MemoryStream();

            var fdt = new FastDFSTool();
            var node = await fdt.nodeAsync();
            long len = 1024;
            while (len>0)
            {
                var buf = await FastDFSClient.DownloadFileAsync(node, fileName, offset, len);
                stm.Write(buf, 0, (int)len);
                offset+=len;
                len=(size-offset)>len ? len : (size-offset);
            }

            byte[] data = new byte[size];
            stm.Seek(0, SeekOrigin.Begin);
            stm.Read(data, 0, data.Length);
            stm.Close();

            return data;
        }

        public static async Task<FDFSFileInfo> queryAsync(string fileName)
        {
            FastDFSTool fdt = new FastDFSTool();
            var node = await fdt.nodeAsync();
            return await FastDFSClient.GetFileInfoAsync(node, fileName);
        }
        

        public async Task<StorageNode> nodeAsync()
        {
            ConnectionManager.Initialize(this.trackers);
            return await FastDFSClient.GetStorageNodeAsync(this.groupName);
        }
    }
}